import { CHANGELOG } from "../changelog";
import { globalConfig } from "../config/global";
import { State } from "../core/state";
import { createLogger } from "../core/utils/logging";
import { waitNextFrame } from "../core/utils/utils";
import { getRandomHint } from "../game/hints";

const logger = createLogger('state/preload')

const VERSION_UPDATE = 'version-update';
const VERSION_NO_UPDATE = 'version-no-update';

export class PreloadState extends State {
	constructor() {
		super("PreloadState");
	}

	getInnerHTML() {
		return `
      <div class="loadingImage"></div>
      <div class="loadingStatus">
        <span class="desc">初始化中</span>
      </div>
      <span class="prefab_GameHint"></span>
    `;
	}

	getHasFadeIn() {
		return false;
	}

  getThemeMusic(){
    return null;
  }

	onEnter() {
		this.htmlElement.classList.add("prefab_LoadingState");

		/** @type {HTMLElement} */
		this.statusText = this.htmlElement.querySelector(".loadingStatus > .desc");
		/** @type {HTMLElement} */
		this.hintsText = this.htmlElement.querySelector(".prefab_GameHint");

    this.lastHintShown = -1000;
    this.nextHintDuration = 0;

    this.startLoading();
	}

  startLoading(){
    this.setStatus('初始化中')
      .then(() => this.setStatus('实例化平台类'))
      .then(() => {
        return new Promise(resolve => {
          if(!G_IS_MOBILE_APP || (G_IS_DEV && !globalConfig.debug.platformOnApp)){
            this.app.loadPlatform('browser');
            resolve();
          } else {
            document.addEventListener('plusready', () => {
              this.app.loadPlatform('plus');
              resolve();
            })
          }
        })
      })

      .then(() => this.setStatus('检测存储功能是否可用'))
      .then(() => {
        try{
          window.localStorage.setItem('local_storage_test', '1');
          window.localStorage.removeItem('local_storage_test');
        } catch(err){
          logger.error('localStorage读写出错: ', err);
          return new Promise(() => {
            alert('你的浏览器不支持存储功能，请升级浏览器或启用存储功能。');
          })
        }
      })

      .then(() => this.setStatus('初始化存储类'))
      .then(() => {
        return this.app.storage.initialize();
      })

      .then(() => this.setStatus('初始化设置类'))
      .then(() => {
        return this.app.setting.initialize();
      })

      .then(() => this.setStatus('初始化音乐类'))
      .then(() => {
        return this.app.sound.initialize();
      })

      .then(() => this.setStatus('初始化游戏数据类'))
      .then(() => {
        return Promise.all([
          this.app.savegame.initialize(),
        ])
      })

      .then(() => this.setStatus('加载图片、音乐等资源'))
      .then(() => {
        return this.app.resourceLoader.startLoading();
      })

      .then(() => this.setStatus('检测是否有更新'))
      .then(() => {
        return new Promise(resolve => {
          if(this.app.platform.getIsLiveUpdate()){
            this.app.api.getVersion().then(res => {
              // alert(`server: ${res.data.version}` + ` local: ${G_BUILD_VERSION}` + ` 结果: ${res.data.version.replace(/\./g, '') > G_BUILD_VERSION.replace(/\./g, '')}`);
              if(res.data.version.replace(/\./g, '') != G_BUILD_VERSION.replace(/\./g, '')){
                resolve(VERSION_UPDATE);
              } else {
                resolve(VERSION_NO_UPDATE);
              }
            })
          } else {
            resolve(VERSION_NO_UPDATE);
          }
          // return Promise.resolve();
        })
      })

      .then(res => {
        return new Promise(resolve => {
          // alert(`Promise get result: ${res} 结果: ${res === VERSION_UPDATE}`)
          if(res === VERSION_UPDATE || (G_IS_DEV && globalConfig.debug.liveUpdate)){
            waitNextFrame().then(() => {
              const updateDialog = this.dialogs.showInfo('检查到新版本', 
              `是否更新？当然你不更新也是可以的`,
              ['cancel:bad:取消:timeout', 'ok:good:确认更新']);

              updateDialog.ok.add(() => {
                this.app.platform.liveUpdate(resolve, this.dialogs);
              })
              updateDialog.cancel.add(() => {
                resolve();
              })
            })
          } else {
            resolve();
          }
        })
      })

      .then(() => this.setStatus('确认更新记录'))
      .then(() => {
        return this.app.storage
          .readFileAsync('lastversion')
          .catch(err => {
            logger.warn('Failed to read lastversion:', err)
            return G_BUILD_VERSION;
          })
          .then(version => {
            logger.log('Last version:', version, 'App version:', G_BUILD_VERSION);
            this.app.storage.writeFileAsync('lastversion', G_BUILD_VERSION);
            return version;
          })
          .then(version => {
            let changelogEntries = [];
            logger.log('Last seen version:', version);

            for(let i = 0; i < CHANGELOG.length; i++){
              if(CHANGELOG[i].version === version){
                break;
              }
              changelogEntries.push(CHANGELOG[i])
            }
            if(changelogEntries.length === 0){
              return;
            }

            let dialogHtml = '以下为游戏最新更新内容:';
            for(let i = 0; i < changelogEntries.length; i++){
              const entry = changelogEntries[i]
              dialogHtml += `
                <div class="changelogDialogEntry" data-changelog-skin="
                  ${entry.skin || 'default'}
                ">
                  <span class="version">${entry.version}</span>
                  <span class="date">${entry.date}</span>
                  <ul class="changes">
                    ${entry.entries.map(text => `<li>${text}</li>`).join('')}
                  </ul>
                </div>
              `
            }

            return new Promise(resolve => {
              this.dialogs.showInfo('新内容更新啦！', dialogHtml).ok.add(resolve);
            })
          })
      })
      
      .then(() => this.setStatus('启动'))
      .then(
        () => {
          if(G_IS_DEV && globalConfig.debug.defaultToState){
            this.moveToState(globalConfig.debug.defaultToState);
          } else {
            this.moveToState('MainMenuState');
          }
        },
        err => {
          this.showFailMessage(err);
        }
      )
  }

  showFailMessage(err){
    logger.error('程序初始化错误: ', err);

    const email = 'jialeliang@qq.com';
    const subElement = document.createElement('div');
    subElement.classList.add('failureBox');

    subElement.innerHTML = `
      <div class="logo">
        <img src="res/ui/logo2.png" alt="穿越到修仙世界从零开始"/>
      </div>
      <div class="failureInner">
        <div class="errorHeader">
          初始化程序过程中出错
        </div>
        <div class="errorMessage">
          ${this.currentStatus} 出错:<br>
          ${err}
        </div>

        <div class="supportHelp">
          你可以通过邮箱告知我出了什么问题。
          <br /><a class="email" href="mailto:${email}?subject="App init failed">${email}</a>
        </div>

        <div class="lower">
          <button class="resetApp styledButton">重置</button>
          <i>Build ${G_BUILD_VERSION} @ ${G_BUILD_COMMIT_HASH}</i>
        </div>
      </div>
    `;

    this.htmlElement.classList.add('failure')
    this.htmlElement.appendChild(subElement);

    const resetBtn = subElement.querySelector('.resetApp')
    this.trackClicks(resetBtn, this.showResetConfirm);

    this.hintsText.remove();
  }

  showResetConfirm(){
    if(confirm('你确认重置程序吗，这将会删除你所有设置及存档')){
      this.resetApp();
    }
  }

  resetApp(){
    window.location.reload();
  }

  setStatus(text){
    logger.log("✅ " + text);
    this.currentStatus = text;
    this.statusText.innerText = text;
    // return new Promise(resolve => setTimeout(resolve, 200));
    return Promise.resolve();
  }

	onRender() {
    const now = performance.now();
    if(now - this.lastHintShown > this.nextHintDuration){
			this.lastHintShown = now;
      const hintText = getRandomHint();

			this.hintsText.innerHTML = hintText;

			/**
       * 以每分钟500个字符的阅读速度计算
			 */
			this.nextHintDuration = Math.max(2500, (hintText.length / 500) * 60 * 1000);
		}
  }
}